/****************************************************************************
 *
 * MODULE:             UDP Home sensor demo - SimpleSend
 *
 * REVISION:           $Revision: 12230 $
 *
 * DATED:              $Date: 2009-04-21 11:09:04 +0100 (Tue, 21 Apr 2009) $
 *
 * AUTHOR:             DGAVE
 *
 * DESCRIPTION:
 * Starts the stack and sends a single UDP packet
 *
 *
 ****************************************************************************/

/****************************************************************************/
/***        Include files                                                 ***/
/****************************************************************************/
#include "JIP.h"
#include "Printf.h"
#include "SensorDemoConfig.h"

/****************************************************************************/
/***        Local Variables                                               ***/
/****************************************************************************/

/* Buffer passed to stack for packet management */
PRIVATE uint8 au8PacketBuffer[PACKET_BUFFER_SIZE] __attribute__ ((aligned (4)));


/****************************************************************************
 *
 * NAME: AppColdStart
 *
 * DESCRIPTION:
 * Entry point for application. Initialises system, starts scan then
 * processes interrupts.
 *
 * RETURNS:
 * void, never returns
 *
 ****************************************************************************/
PUBLIC void AppColdStart(void)
{
    tsStackInitData sStackData;

#ifdef HIGH_POWER_MODULE
        /* enable external PA for high power module */
        vAHI_HighPowerModuleEnable(TRUE, TRUE);
#endif

    /* Enable UART for debug output */

    vJIP_InitHardware();

	vUART_printInit();

    vPrintf("\nSimple Send Cold Start.\n");

    /*
     * JenNet and lower level parameters
     */
    sStackData.eLinkLayer = E_LINKLAYER_JENNET; /* Run 6LowPAN on top of the Jennet network */
    sStackData.eDeviceType = E_JIP_END_DEVICE; /* We are an end device */
    sStackData.u16PanId = PAN_ID; /* PAN ID, channel and network ID must match the coordinator on the gateway */
    sStackData.u32Channel = CHANNEL_BITMAP;
    sStackData.u32NetworkId = NETWORK_APPLICATION_ID;

    /*
     * JIP 6LowPAN parameters
     */
    sStackData.u64AddressPrefix = ADDRESS_PREFIX; /* IPv6 address prefix - must match coordinator and gateway. */
    sStackData.pau8PacketBuffer = au8PacketBuffer; /* Buffer for JIP to store IPv6 packets. */
    sStackData.u32PacketBufferSize = PACKET_BUFFER_SIZE;
    sStackData.u8Sockets = 8; /* Maximum number of sockets that can be created. */
    sStackData.u16maxMTU = MAX_MTU; /* Maximum size of an IPv6 frame. */

    if (iJIP_InitStack(&sStackData) == -1)
    {
        /* Error! */
        vPrintf("Failed to start - iJIP_InitStack set error code %x.\n", u32JIP_GetErrNo());
    }
    else
    {
        vPrintf("InitStack returned OK.  Number of packet buffers %d.\n", sStackData.u16NumPacketBuffers);
    }

    /* Loop forever as we are event driven from here on */
    while (1)
        ;
}

/****************************************************************************
 *
 * NAME: vJIP_StackEvent
 *
 * DESCRIPTION:
 * Processes any incoming stack events. This is involved with 802.15.4 MAC
 * stack activity. It is important here to ensure that the application does
 * not attempt any communications until the device has joined the wireless
 * network.
 * Once a join indication has been received, we create a socket and send the packet.
 *
 * PARAMETERS: Name          RW Usage
 *             eEvent        R  Stack event
 *             pu8Data       R  Additional information associated with event
 *             u8DataLen     R  Length of additional information
 *
 ****************************************************************************/
PUBLIC void vJIP_StackEvent(teJIP_StackEvent eEvent, uint8 *pu8Data, uint8 u8DataLen)
{

    switch (eEvent)
    {
    case E_STACK_JOINED:
        vPrintf("Joined Network\n");

        int iSocket = -1;
        /*
         * Create a new socket.
         * The flags must be as below, JIP currently only supports IPv6 UDP sockets.
         */
        iSocket = iJIP_Socket(E_JIP_PF_INET6, E_JIP_SOCK_DGRAM, E_JIP_PROTOCOL_ONLY_ONE);

        if (iSocket == -1)
        {
            /* Error! */
            vPrintf("Unable to create socket.  Error code %x.\n", u32JIP_GetErrNo());
            return;
        }

        vPrintf("Socket created OK.\n");
        /* Bind socket: this is to enable source port to be specified
         * The TRUE parameter means generate a global address (2001:1000:)
         * rather than a link local (fe80::)
         * This is important when sending through a gateway, so the remote PC
         * knows the full address to send commands to.
         */
        tsJIP_SockAddr sAddr;
        (void) iJIP_GetOwnDeviceAddress(&sAddr, TRUE);

        sAddr.sin6_port = PC_UDP_PORT;

        if (iJIP_Bind(iSocket, &sAddr, sizeof(tsJIP_SockAddr)) == -1)
        {
            /* Error! */
            vPrintf("Unable to bind socket.  Error code %x.\n", u32JIP_GetErrNo());
            return;
        }


        /*
         * Set the IPv6 address and destination port for the packet
         */
        sAddr.sin6_family = E_JIP_PF_INET6;
        sAddr.sin6_addr.s6_addr32[0] = PC_ADDR_0;
        sAddr.sin6_addr.s6_addr32[1] = PC_ADDR_1;
        sAddr.sin6_addr.s6_addr32[2] = PC_ADDR_2;
        sAddr.sin6_addr.s6_addr32[3] = PC_ADDR_3;
        sAddr.sin6_port = PC_UDP_PORT;

        /*
         * Get a transmit buffer from JIP.
         * pu8Payload points to the UDP payload section of the buffer.
         * There will be (MTU - UDP/IP header) bytes available for our data.
         * If  iJIP_GetDataBuffer returns non zero, JIP has run out of IPv6 buffers.
         */
        uint8 *pu8Payload;
        if (iJIP_GetDataBuffer(&pu8Payload) != 0)
        {
            /* Error! */
              vPrintf("Failed to get buffer.  Error code %x.\n", u32JIP_GetErrNo());
              return;
        }
        /* The first byte indicates the type of packet - readings from the sensor to the PC */
        pu8Payload[0] = 'O';
        pu8Payload[1] = 1;
        pu8Payload[2] = 'G';
        pu8Payload[3] = 'l';
        pu8Payload[4] = 'o';
        pu8Payload[5] = 'H';
        pu8Payload[6] = 'e';
        pu8Payload[7] = 'l';
        pu8Payload[8] = 'l';
        pu8Payload[9] = 'o';
        //char mess[8] = "Hello";


        /*
         * Transmit the data in the buffer.
         * iSocket contains the source port.
         * pu8Payload / TRANSMIT_PAYLOAD_SIZE is the data to send.
         * 0 (flags) are not currently used in JIP.
         * sAddr / sizeof(tsJIP_SockAddr) contain the address and destination port.
         */
    /***    if (iJIP_SendTo(iSocket, pu8Payload, TRANSMIT_PAYLOAD_SIZE, 0, &sAddr, sizeof(tsJIP_SockAddr)) == -1) ****/


        if (iJIP_SendTo(iSocket, pu8Payload, TRANSMIT_PAYLOAD_SIZE, 0, &sAddr, sizeof(tsJIP_SockAddr)) == -1)
        {
            vPrintf("iJIP_SendTo failed.  Error code %x.\n", u32JIP_GetErrNo());
            return;
        }
        vPrintf("Packet has been sent\n");
        break;
    default:
        break;
    }
}

PUBLIC void AppWarmStart(void)
{
}
PUBLIC void vJIP_PeripheralEvent(uint32 u32Device, uint32 u32ItemBitmap)
{
}

PUBLIC void vJIP_DataEvent(int iSocket, teJIP_DataEvent eEvent, tsJIP_SockAddr *psAddr, uint8 u8AddrLen)
{
}

PUBLIC void vJIP_ConfigureNetwork(tsNetworkConfigData *psNetworkConfigData)
{
}
